<!--
 * @Author: wangshuixin 2412658453@qq.com
 * @Date: 2024-11-21 08:53:25
 * @LastEditors: wangshuixin 2412658453@qq.com
 * @LastEditTime: 2025-01-21 10:37:25
 * @FilePath: \sr_system_manager_ui\src\views\resultsManagement\components\PersonInfo\index.vue
 * @Description: 人员信息 组件
-->
<script setup lang="ts">
import type { TableColumnItem } from '@/types/component'

const props = defineProps({
  /* 模块类型：college 学院成果管理；office 科研处成果管理；mine 我的成果； */
  moduleType: {
    type: String as PropType<'college' | 'office' | 'mine'>,
    default: 'college',
  },
  /* 是否可编辑 */
  editable: {
    type: Boolean,
    default: false
  },
  /* 表头设置 */
  columns: {
    type: Array as () => TableColumnItem[],
    default: []
  },
  /* 人员信息已填写数据 */
  personDataList: {
    type: Array,
    default: []
  },
  /* 可选择的人员列表 */
  optionPersonList: {
    type: Array,
    default: []
  },
  /* 总字数 */
  totalCount: {
    type: Number,
  }
})

const emits = defineEmits(['update:personDataList', 'delete'])

// 表单引用
const tableForm = ref()
// 校验表单数据
const formData = ref<{
  tableData: any[]
}>({
  tableData: computed(() => { return props.personDataList }),
})
// 人员信息中，统计的人员字数总和
const wordsCount = ref()
// 人员类型
const memberTypeList = ref([
  {
    title: "校内人员",
    value: 1,
  }, {
    title: "校外人员",
    value: 0,
  }
])
// 可选的人员信息
const optionPersonList = ref([])
/* 可选择的人员列表的原始数据 */
const originalOptionPersonList = computed(() => { return props.optionPersonList })
// 角色 1:第一作者，2：通讯作者，3：参编作者
const roleList = ref([
  {
    title: "第一作者",
    value: 1,
    disabled: false
  }, {
    title: "通讯作者",
    value: 2,
    disabled: false
  }, {
    title: "参编作者",
    value: 3,
    disabled: false
  }
])

// 新增角色
const addRole = () => {
  const role = {
    accountId: undefined,
    name: undefined,
    code: undefined,
    type: 1, // 默认校内人员
    memberWordCount: undefined,
    role: undefined
  }
  formData.value.tableData.push(role)
}

// 人员信息 >> 按姓名和工号搜索
const customFilterMethod = (searchKey: string) => {
  if (searchKey !== '') {
    nextTick(() => {
      optionPersonList.value = originalOptionPersonList.value.filter((person: any) => { return person.name.includes(searchKey) || person.code.includes(searchKey)})
    })
  } else {
    optionPersonList.value = originalOptionPersonList.value
  }
}

// 选择人员
const selectPerson = (accountId: string, rowIndex: number) => {
  const person = originalOptionPersonList.value.filter((person: any) => {
    return person.accountId === accountId
  })[0]
  formData.value.tableData[rowIndex].accountId = accountId
  formData.value.tableData[rowIndex].name = person.name
  formData.value.tableData[rowIndex].code = person.code
  tableForm.value.clearValidate([`tableData[${rowIndex}].name`])
}

// 删除一行人员信息数据
const deleteRowPersonInfo = (rowIndex: number) => {
  emits('delete', rowIndex)
}

// 人员信息 变动
watch(
  () => formData.value.tableData,
  () => {
    if (formData.value.tableData.some(item => item.role === 1)) {
      roleList.value[0].disabled = true
    } else {
      roleList.value[0].disabled = false
    }
    if (formData.value.tableData.some(item => item.role === 2)) {
      roleList.value[1].disabled = true
    } else {
      roleList.value[1].disabled = false
    }
    // 先重置人员是否可选
    originalOptionPersonList.value.forEach(item => {
      item.disabled = false
    })
    // 判断是否已选中
    formData.value.tableData.forEach(person => {
      originalOptionPersonList.value.forEach(item => {
        if (item.accountId === person.accountId) {
          item.disabled = true
        }
      })
    })
    emits("update:personDataList", formData.value.tableData)
  }, {
    immediate: true,
    deep: true
  }
)

// 表单校验
const checkTableFormValidate = (callback: Function) => {
  tableForm.value?.validate().then(() => {
    callback()
  }).catch((err) => {
    // 要排除的字段
    const excludeFields = [
      "tableData[-1].name",
      "tableData[-1].role",
      "tableData[-1].memberWordCount",
    ]
    // 提取错误信息，排除特定字段
    let errors = undefined
    for (const field in err) {
      if (err.hasOwnProperty(field) && !excludeFields.includes(field)) {
        errors = err[field];
      }
    }
    if (callback) {
      callback(errors)
    }
  })
}

watch(
  () => props.personDataList,
  () => {
    wordsCount.value = 0
    props.personDataList.forEach((person: any) => {
      wordsCount.value += person.memberWordCount ?? 0
    })
  }, {
    immediate: true,
    deep: true
  }
)

watch(
  () => props.optionPersonList,
  () => {
    if (props.optionPersonList) {
      optionPersonList.value = props.optionPersonList
    }
  }, {
    immediate: true,
    deep: true
  }
)

defineExpose({
  checkTableFormValidate,
  params: formData.value.tableData
})

</script>

<template>
  <div class="apply-record" style="padding-bottom: 24px;">
    <div class="area-title">
      人员信息
      <el-button
        v-if="props.editable && formData.tableData.length < 20"
        type="primary" style="margin-top: -6px;" @click="addRole">新增角色</el-button>
    </div>
    <div>
      <el-form ref="tableForm" :model="formData" class="checked-padding">
        <x-table-form
          :data="formData.tableData"
          :columns="props.columns.filter(item => formData.tableData.length === 1 || !props.editable ? item.title !== '操作' : true)"
          :auto-height="true"
        >
          <template #index="{ rowIndex }">
            {{ rowIndex + 1 }}
          </template>
          <template #type="{ record }">
            <el-select
              v-if="props.editable"
              v-model="record.type"
              placeholder="请选择"
              @change="(type) => { record.name = undefined, record.accountId = undefined, record.code = type === 0 ? '-' : undefined }"
            >
              <el-option
                v-for="option in memberTypeList"
                :key="option.value"
                :label="option.title"
                :value="option.value"
              />
            </el-select>
            <span v-else>{{ record.type === 1 ? '校内人员' : '校外人员' }}</span>
          </template>
          <template #name="{ record, column, rowIndex }">
            <el-form-item
              v-if="props.editable && record.type === 1"
              :prop="`tableData[${rowIndex}].name`"
              label-width="0px"
              :rules="column.config ? column.config.rules : []"
              validate="change"
            >
              <el-select
                v-model="record.accountId"
                filterable
                :filter-method="customFilterMethod"
                placeholder="请选择"
                @change="(accountId) => selectPerson(accountId, rowIndex)"
              >
                <el-option
                  v-for="option in optionPersonList"
                  :key="option.value"
                  :label="option.title"
                  :value="option.value"
                  :disabled="option.disabled"
                />
              </el-select>
            </el-form-item>
            <el-form-item
              v-else-if="props.editable && record.type === 0"
              :prop="`tableData[${rowIndex}].name`"
              label-width="0px"
              :rules="column.config ? column.config.rules : []"
              validate="blur"
            >
              <el-input
                type="text"
                v-model="record.name"
                :maxlength="10"
                placeholder="请输入"
              />
            </el-form-item>
            <span v-else>{{ record.name }}</span>
          </template>
          <template #role="{ record, column, rowIndex }">
            <el-form-item
              v-if="props.editable"
              :prop="`tableData[${rowIndex}].role`"
              label-width="0px"
              :rules="column.config ? column.config.rules : []"
              validate="change"
            >
              <el-select
                v-model="record.role"
                placeholder="请选择"
                @change="() => tableForm.clearValidate([`tableData[${rowIndex}].role`])"
              >
                <el-option
                  v-for="option in roleList"
                  :key="option.value"
                  :label="option.title"
                  :value="option.value"
                  :disabled="option.disabled"
                />
              </el-select>
            </el-form-item>
            <span v-else>{{ record.role === 1 ? '第一作者' : (record.role === 2 ? '通讯作者' : (record.role === 3 ? '参编作者' : '')) }}</span>
          </template>
          <template #memberWordCount="{ record, column, rowIndex }">
            <el-form-item
              v-if="props.editable"
              :prop="`tableData[${rowIndex}].memberWordCount`"
              label-width="0px"
              :rules="column.config ? column.config.rules : []"
              validate="blur"
            >
              <el-input-number
                v-model="record.memberWordCount"
                :min="1"
                :max="99999999"
                :step="1"
                :step-strictly="true"
                :controls="false"
                style="width: 100%;"
                placeholder="请输入"
              />
            </el-form-item>
          </template>
          <template #option="{ rowIndex }">
            <el-button
              v-if="formData.tableData.length > 1"
              type="danger"
              link
              @click="deleteRowPersonInfo(rowIndex)"
            >
              删除
            </el-button>
          </template>
        </x-table-form>
        <div v-if="props.totalCount && props.totalCount !== wordsCount" class="total-row">
          <div style="margin-right: 86px;color: #F56C6C;">字数之和不等于总字数</div>
        </div>
      </el-form>
    </div>
  </div>
</template>

<style scoped lang="scss">
.apply-record {
  display: flex;
  flex-direction: column;
  height: auto;
  background-color: white;
  padding-left: 20px;
  padding-right: 20px;

  .area-title {
    height: 20px;
    font-weight: bold;
    color: #1D2129;
    font-size: 14px;
    margin-bottom: 16px;
    display: flex;
    justify-content: space-between;

    :deep(.el-button) {
      height: 32px;
    }
  }
  .total-row {
    display: flex;
    justify-content: flex-end;
    height: 32px;
    line-height: 32px;
  }
  :deep(.el-form-item) {
    margin-bottom: 0px;
  }
  :deep(.el-table .cell) {
    overflow: visible;
    padding-top: 16px !important;
    padding-bottom: 16px !important;
  }
  .checked-padding {
    :deep(.el-table__cell) {
      padding: 16px 0px;
    }
  }
}
</style>